/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fr.istia.gesstages.dao.db;

import fr.istia.gesstages.dao.IDaoOffer;
import fr.istia.gesstages.exception.PortailException;
import fr.istia.gesstages.jpa.Offer;
import fr.istia.gesstages.jpa.User;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.transaction.annotation.Transactional;

/**
 * @date 22/11/2011
 * @author Cédric Moreau
 */
@Transactional
public class DaoOfferDB implements IDaoOffer {

    @PersistenceContext
    private EntityManager em;

    public Offer create(Offer offer) {
        try {
            em.persist(offer);
            return offer;
        } catch (Exception e) {
            throw new PortailException("Erreur lors de la persistance de l'offre '" + offer.getTitre() + "'", e);
        }
    }

    public Offer update(Offer offer) {
        try {
            return em.merge(offer);
        } catch (Exception e) {
            throw new UnsupportedOperationException(" Erreur lors de la modification");
        }
    }

    public void delete(Offer offer) {
        try {
            em.remove(em.merge(offer));
        } catch (Exception e) {
            throw new UnsupportedOperationException(" Erreur lors de la suppression");
        }
    }

    public Offer find(int id) {
        try {
            return (Offer) em.find((Offer.class), id);
        } catch (Exception e) {
            throw new UnsupportedOperationException("Erreur lors de la recherche");
        }
    }

    public List<Offer> findAll() {
        try {
            return em.createQuery("SELECT o From Offer o").getResultList();
        } catch (Exception e) {
            throw new PortailException("Erreur lors de la récupération de toutes les offres", e);
        }
    }

    public List<Offer> findArchived(String year) {
        try {
            List<Offer> offers = em.createQuery("select o from Offer o where o.archive = 1").getResultList();
            return offers;
        } catch (Exception e) {
            throw new UnsupportedOperationException(" Erreur lors de la recuperation des offres archivees");
        }
    }

    public List<Offer> findCurrent() {
        try {
            return em.createQuery("SELECT o FROM Offer o WHERE o.archive = 0").getResultList();
        } catch (Exception e) {
            throw new PortailException("Erreur lors de la récupération des offres du moment", e);
        }
    }

    public void archiveAll() {
        List<Offer> offers = findAll();
        for (Offer o : offers) {
            o.setArchive(true);
            update(o);
        }
    }

    public void deleteAll() {
        try {
            em.createQuery("DELETE FROM Offer o").executeUpdate();
        } catch (Exception e) {
            throw new PortailException("Erreur lors de la suppression de toutes les offres");
        }
    }

    public List<Offer> findNotAppliedBy(User student) {
        try {
            List<Offer> lesOffres;
            lesOffres = em.createQuery("SELECT o FROM Offer o WHERE NOT EXISTS(SELECT a FROM Apply a WHERE o.id = a.stage.id)").getResultList();
            lesOffres.addAll(em.createQuery("SELECT o FROM Offer o, Apply a WHERE o.id = a.id AND a.user.id != :idUser").setParameter("idUser", student.getId()).getResultList());
            return lesOffres;
        } catch (Exception e) {
            throw new PortailException("Erreur lors de la récupération des offres non postulées par l'utilisateur '" + student.getLogin() + "'", e);
        }
    }
}
